package com.dtw.ditouwang.ui.movement;

import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.services.weather.LocalWeatherForecastResult;
import com.amap.api.services.weather.LocalWeatherLiveResult;
import com.amap.api.services.weather.WeatherSearch;
import com.amap.api.services.weather.WeatherSearchQuery;
import com.dtw.ditouwang.BuildConfig;
import com.dtw.ditouwang.R;
import com.dtw.ditouwang.beans.ChallengeListBean;
import com.dtw.ditouwang.beans.MovementBackBean;
import com.dtw.ditouwang.beans.MovementUpdateBean;
import com.dtw.ditouwang.repositories.UserRepository;
import com.dtw.ditouwang.ui.BaseActivity;
import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MovementOutSideActivity extends BaseActivity implements View.OnClickListener, AMap.OnMyLocationChangeListener, SensorEventListener {
    MapView mapView;
    AMap aMap;
    private TextView textDistance;
    private TextView textSpeed;
    private TextView textTime;
    private TextView textCalorie;
    ImageView countdownImg;
    /**
     * 继续
     */
    private Button textContinue;
    /**
     * 结束
     */
    private Button textStop;
    private LinearLayout viewPaused;
    /**
     * 暂停
     */
    private Button textPause;
    private LinearLayout viewStarted;

    List<LatLng> latLngs = new ArrayList<>();
    long movementTimeSecond = 0;
    float distance = 0;
    ChallengeListBean.DataBean challengeBean;
    SensorManager sensorManager;
    Sensor sensor;
    int startStep = -1, step = 0;
    AMapLocationClient aMapLocationClient;
    String weather = "晴";
    String walk = "健走";
    List<MovementUpdateBean.SubsectionBean.ValueBean> avgEveryMintus = new ArrayList<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
        }
        setContentView(R.layout.activity_movement_outside);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().setStatusBarColor(Color.BLACK);
        }
        initView();
        //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState)，创建地图
        challengeBean = getIntent().getParcelableExtra(MovementChallengeActivity.KeyChallengeBean);
        if (!challengeBean.isWalk()) {
            walk = "跑步";
        }
        setTitle("室外" + walk);
        mapView.onCreate(savedInstanceState);
        aMap = mapView.getMap();
        aMap.getUiSettings().setZoomControlsEnabled(false);
        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        getWeather();
        new CountDownTimer(3100, 1000) {

            @Override
            public void onTick(long l) {
                if (l < 2000) {
                    countdownImg.setImageResource(R.drawable.pic_1);
                } else if (l < 3000) {
                    countdownImg.setImageResource(R.drawable.pic_2);
                }
            }

            @Override
            public void onFinish() {
                countdownImg.setVisibility(View.GONE);
                enableLocation();
                startMovement();
            }
        }.start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    private void initView() {
        mapView = findViewById(R.id.map);
        textDistance = findViewById(R.id.text_distance);
        textSpeed = findViewById(R.id.text_speed);
        textTime = findViewById(R.id.text_time);
        textCalorie = findViewById(R.id.text_calorie);
        textContinue = findViewById(R.id.text_continue);
        textContinue.setOnClickListener(this);
        textStop = findViewById(R.id.text_stop);
        textStop.setOnClickListener(this);
        viewPaused = findViewById(R.id.view_paused);
        textPause = findViewById(R.id.text_pause);
        textPause.setOnClickListener(this);
        viewStarted = findViewById(R.id.view_started);
        countdownImg = findViewById(R.id.img_coundown);
        textDistance.setText(Html.fromHtml("<font><big><big><big><big>0.00</big></big></big></big></font><br>公里"));
        textTime.setText(Html.fromHtml("<font><big><big><big><big>0′00″</big></big></big></big></font><br>时间"));
        textSpeed.setText(Html.fromHtml("<font><big><big><big><big>0′00″</big></big></big></big></font><br>配速"));
        textCalorie.setText(Html.fromHtml("<font><big><big><big><big>0</big></big></big></big></font><br>消耗"));

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            default:
                break;
            case R.id.text_continue:
                viewStarted.setVisibility(View.VISIBLE);
                viewPaused.setVisibility(View.GONE);
                enableLocation();
                startMovement();
                break;
            case R.id.text_stop:
                if (BuildConfig.DEBUG) {
                    if (step == 0)
                        step = 100;
                    if (distance == 0)
                        distance = 100;
                }
                if (step == 0 || distance == 0) {
                    showToast("运动距离太短无法保存");
                    return;
                }
                stopMovement();
                aMap.setMyLocationEnabled(false);
                MovementUpdateBean movementUpdateBean = new MovementUpdateBean();
                movementUpdateBean.setId(UserRepository.getInstance().getUserID());
                movementUpdateBean.setAvg_speed(distance / 1000 / (movementTimeSecond / 60f / 60f));
                movementUpdateBean.setChallenge_id(challengeBean.getId());
                movementUpdateBean.setIs_challenge(challengeBean.isChallenge() ? 1 : 0);
                movementUpdateBean.setMileage(String.format("%.2f", distance / 1000f));
                movementUpdateBean.setQuantity(50 * movementTimeSecond / 60f / 60 * 30 / (movementTimeSecond / 60f / (long) distance * 400f));
                movementUpdateBean.setRoom_type(2);
                movementUpdateBean.setSpeed_distribution(movementTimeSecond / (distance / 1000f));
                movementUpdateBean.setStep(step);
                movementUpdateBean.setStep_frequency(step / (movementTimeSecond / 60f));
                movementUpdateBean.setStride((int) distance * 100 / step);
                movementUpdateBean.setTime((int) movementTimeSecond);
                movementUpdateBean.setType(challengeBean.isWalk() ? 1 : 2);
                movementUpdateBean.setWeather(weather);
                movementUpdateBean.setTrajectory(latLngs);
                MovementUpdateBean.SubsectionBean subsectionBean = new MovementUpdateBean.SubsectionBean();
                subsectionBean.setMovementTime((int) movementTimeSecond / 60);
                subsectionBean.setValues(avgEveryMintus);
                movementUpdateBean.setSubsection(subsectionBean);
                if (Float.isInfinite(movementUpdateBean.getAvg_speed())) {
                    movementUpdateBean.setAvg_speed(0);
                }
                if (Float.isInfinite(movementUpdateBean.getStep_frequency())) {
                    movementUpdateBean.setStep_frequency(0);
                }
                if (Float.isNaN(movementUpdateBean.getQuantity())) {
                    movementUpdateBean.setQuantity(0);
                }
//                if (BuildConfig.DEBUG == true) {
//                    MovementUpdateBean.SubsectionBean subsectionBeandebug = new MovementUpdateBean.SubsectionBean();
//                    subsectionBeandebug.setMovementTime(20);
//                    for (int i = 0; i < 150; i++) {
//                        MovementUpdateBean.SubsectionBean.ValueBean valueBean = new MovementUpdateBean.SubsectionBean.ValueBean();
//                        valueBean.setValue(new Random().nextInt(50));
//                        avgEveryMintus.add(valueBean);
//                    }
//                    subsectionBeandebug.setValues(avgEveryMintus);
//                    movementUpdateBean.setSubsection(subsectionBeandebug);
//                }
                webApi.upLoadMovement(new Gson().toJson(movementUpdateBean)).enqueue(new Callback<MovementBackBean>() {
                    @Override
                    public void onResponse(Call<MovementBackBean> call, Response<MovementBackBean> response) {
                        if (response.body().isResult()) {
                            Intent intent = new Intent(MovementOutSideActivity.this, MovementOverActivity.class);
                            intent.putExtra(MovementOverActivity.KeyMoovementOverData, response.body().getData());
                            startActivity(intent);
                            finish();
                        }
                    }

                    @Override
                    public void onFailure(Call<MovementBackBean> call, Throwable t) {
//                        Log.i("dtw", t.getMessage());
                    }
                });
                break;
            case R.id.text_pause:
                stopMovement();
                viewStarted.setVisibility(View.GONE);
                viewPaused.setVisibility(View.VISIBLE);
                aMap.setMyLocationEnabled(false);
                break;
        }
    }

    @Override
    public void onBackPressed() {
        new AlertDialog.Builder(this).setMessage("当前数据尚未保存，是否离开").setPositiveButton("留下", null)
                .setNegativeButton("留下", null)
                .setPositiveButton("离开", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        MovementOutSideActivity.super.onBackPressed();
                    }
                }).show();
    }

    public void startMovement() {
        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_COUNTER)) {
            sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
            sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_UI);
        } else if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_DETECTOR)) {
            sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
            sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_UI);
        }
    }

    public void stopMovement() {
        sensorManager.unregisterListener(this);
    }

    public void getWeather() {
        AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
        mLocationOption.setOnceLocation(true);
        aMapLocationClient = new AMapLocationClient(this);
        aMapLocationClient.setLocationListener(new AMapLocationListener() {
            @Override
            public void onLocationChanged(AMapLocation aMapLocation) {
                WeatherSearchQuery mquery = new WeatherSearchQuery(aMapLocation.getCity(), WeatherSearchQuery.WEATHER_TYPE_LIVE);
                WeatherSearch mweathersearch = new WeatherSearch(MovementOutSideActivity.this);
                mweathersearch.setOnWeatherSearchListener(new WeatherSearch.OnWeatherSearchListener() {
                    @Override
                    public void onWeatherLiveSearched(LocalWeatherLiveResult localWeatherLiveResult, int i) {
                        weather = localWeatherLiveResult.getLiveResult().getWeather();
                        Log.i("dtw", "weather：" + localWeatherLiveResult.getLiveResult().getCity() + localWeatherLiveResult.getLiveResult().getWeather());
                    }

                    @Override
                    public void onWeatherForecastSearched(LocalWeatherForecastResult localWeatherForecastResult, int i) {

                    }
                });
                mweathersearch.setQuery(mquery);
                mweathersearch.searchWeatherAsyn(); //异步搜索
            }
        });
        aMapLocationClient.startLocation();
    }

    float lastMinutesDistance = 0;

    @Override
    public void onMyLocationChange(Location location) {
        latLngs.add(new LatLng(location.getLatitude(), location.getLongitude()));
        movementTimeSecond += 2;
        aMap.addPolyline(new PolylineOptions().add(new LatLng(location.getLatitude(), location.getLongitude()))
                .width(10).color(Color.argb(255, 1, 1, 1)));

        textTime.setText(Html.fromHtml("<font><big><big><big><big>" +
                movementTimeSecond / 60 + "′" + String.format("%02d", movementTimeSecond % 60) +
                "″</big></big></big></big></font><br>时间"));
        if (latLngs.size() > 1) {
            distance += AMapUtils.calculateLineDistance(latLngs.get(latLngs.size() - 2), latLngs.get(latLngs.size() - 1));
            textDistance.setText(Html.fromHtml("<font><big><big><big><big>" +
                    String.format("%.2f", distance / 1000) +
                    "</big></big></big></big></font><br>公里"));
        }
        if (distance > 0) {
            float speedSecond = movementTimeSecond / distance * 1000;
            textSpeed.setText(Html.fromHtml("<font><big><big><big><big>" +
                    (int) Math.floor(speedSecond / 60) + "′" + String.format("%02.0f", speedSecond % 60) +
                    "″</big></big></big></big></font><br>配速"));
            if (speedSecond < 80 && movementTimeSecond > 10) {
                showToast("检测到运动异常");
                finish();
            }
        }
        if (distance > 0) {
            float calorie = 50 * movementTimeSecond / 60f / 60 * 30 / (movementTimeSecond / 60f / (long) distance * 400f);
            textCalorie.setText(Html.fromHtml("<font><big><big><big><big>" + String.format("%.0f", calorie) + "</big></big></big></big></font><br>消耗"));
        }
        if (movementTimeSecond % 60 == 0) {
            MovementUpdateBean.SubsectionBean.ValueBean avg = new MovementUpdateBean.SubsectionBean.ValueBean();
            avg.setValue((distance - lastMinutesDistance) / 1000 / (1f / 60));
            avgEveryMintus.add(avg);
            lastMinutesDistance = distance;
        }
    }

    public void enableLocation() {
        MyLocationStyle myLocationStyle;
        myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点，定位点依照设备方向旋转，并且会跟随设备移动。（1秒1次定位）如果不设置myLocationType，默认也会执行此种模式。
        myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔，只在连续定位模式下生效，单次定位模式下不会生效。单位为毫秒。
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE);
        myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.icon_location));
        myLocationStyle.strokeColor(0x00000000);
        myLocationStyle.radiusFillColor(0x00000000);
        aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
//        aMap.getUiSettings().setMyLocationButtonEnabled(true);//设置默认定位按钮是否显示，非必需设置。
        aMap.setOnMyLocationChangeListener(this);
        aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点，false表示隐藏定位蓝点并不进行定位，默认是false
    }

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        if (sensorEvent.sensor.getType() == Sensor.TYPE_STEP_COUNTER) {
            if (startStep == -1) {
                startStep = (int) sensorEvent.values[0];
            }
            step = (int) sensorEvent.values[0] - startStep;
        } else if (sensorEvent.sensor.getType() == Sensor.TYPE_STEP_DETECTOR) {
            step += (int) sensorEvent.values[0];
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }
}
